package com.hex.ds.em.hcdp.gauss.analyze.script.performance;

import static com.hex.ds.em.hcdp.gauss.pack.service.impl.ScriptPackTaskServiceImpl.wordResult;

import cn.hutool.core.util.ReUtil;
import com.hex.ds.em.hcdp.basic.common.IResultForReport;
import com.hex.ds.em.hcdp.gauss.analyze.script.performance.entity.CheckLeftJoinEntity;
import com.hex.ds.em.hcdp.gauss.common.entity.ScriptPackScanResultEntity;
import com.hex.ds.em.hcdp.gauss.common.enums.AntlrEnum;
import com.hex.hdtp.common.utils.AntlrUtil;
import com.hex.hlrt.gauss.g4.basic.gen.GaussParser.Join_clauseContext;
import com.hex.hlrt.gauss.g4.basic.gen.GaussParser.Query_blockContext;
import com.hex.hlrt.gauss.g4.basic.gen.GaussParserBaseListener;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import org.antlr.v4.runtime.tree.ParseTree;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

/**
 * @Package com.hex.ds.em.hcdp.gauss.analyze.script.performance
 * @ClassName CheckLeftJoinListener
 * @Description LEFT JOIN检查
 * @Author gj.xu
 * @Date 2024/9/14 15:52
 * @Version v2.0
 **/
@Slf4j
@Accessors(chain = true)
@Scope(value = "prototype")
@RequiredArgsConstructor(onConstructor_ = @Autowired)
@Service("Gauss-CheckLeftJoin")
public class CheckLeftJoinListener extends GaussParserBaseListener implements IResultForReport {


  @Override
  public void exitQuery_block(Query_blockContext ctx) {
    if (ctx.from_clause() != null && ctx.where_clause() != null) {
      List<ParseTree> parseTrees = AntlrUtil
          .queryDesignateChildrenOfSumObj(ctx.from_clause(), Join_clauseContext.class);
      for (int i = 0; i < parseTrees.size(); i++) {
        Join_clauseContext join_clauseContext = (Join_clauseContext) parseTrees.get(i);
        if (join_clauseContext.outer_join_type() != null && join_clauseContext.outer_join_type()
            .getText().trim()
            .equalsIgnoreCase("LEFT")) {
          //获取LEFT JOIN后的表别名
          String tableName =
              join_clauseContext.table_ref_aux().table_alias() != null ? join_clauseContext
                  .table_ref_aux().table_alias().getText()
                  .trim()
                  : join_clauseContext.table_ref_aux().table_ref_aux_internal().getText().trim();
          //判断WHERE条件是否有 右表.column IS NOT NULL(目前仅考虑这一种情况)
          if (ReUtil
              .contains(tableName.toUpperCase() + "\\s+\\.\\s+[a-zA-Z0-9_]+\\s+IS\\s+NOT\\s+NULL",
                  ctx.where_clause().getText().trim().toUpperCase())) {
            // 更新扫描后word指标结果
            setResultForWordReport();

            CheckLeftJoinEntity ruleEntity = new CheckLeftJoinEntity();
            join_clauseContext.addHeadAnyChild(ruleEntity);
            log.info("rule-[CheckLeftJoin]:");
          }
        }
      }
    }
  }


  @Override
  public void setResultForWordReport() {
    ScriptPackScanResultEntity result = wordResult.get(AntlrEnum.LEFT_JOIN_CHECK.getValue());
    if (result == null) {
      return;
    }
    result.setScanTable("").setScanState("fail");
    wordResult.put(AntlrEnum.LEFT_JOIN_CHECK.getValue(), result);
  }
}
